package com.invengo.module_check.ui.fragment.listing_by_car;

import android.annotation.SuppressLint;
import android.app.Application;
import android.os.Build;

import com.invengo.library_db.entity.module_check.BookBean;
import com.invengo.library_db.entity.module_check.ShelfBean;
import com.invengo.library_rfid.classify.AnalyzeImpl;
import com.invengo.library_rfid.classify.RFIDCallBackListener;
import com.invengo.library_rfid.entity.TagInfo;
import com.invengo.module_check.BR;
import com.invengo.module_check.R;
import com.invengo.module_check.data.repsitory.business.BusinessRepsitory;
import com.invengo.module_check.ui.fragment.listing_by_car.item.ListingByCarItemViewModel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableArrayList;
import androidx.databinding.ObservableList;
import io.reactivex.Observable;
import java8.util.J8Arrays;
import java8.util.stream.Collectors;
import java8.util.stream.StreamSupport;
import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.bus.Messenger;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.http.BaseBean;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.StringUtils;
import me.goldze.mvvmhabit.utils.ToastUtils;
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter;
import me.tatarka.bindingcollectionadapter2.ItemBinding;

import static me.goldze.mvvmhabit.utils.constant.Constants.TOKEN_CAMERA;

public class ListingByCarViewModel extends BaseViewModel<BusinessRepsitory> {
    public RFIDCallBackListener rfidService = new RFIDCallBackListener(AnalyzeImpl.TO_SHELF, tagInfo -> onScanResult(tagInfo), state -> isReading.set(state));
    private String carId;
    public BindingRecyclerViewAdapter adapter =new BindingRecyclerViewAdapter();
    public SingleLiveEvent<String> carName =new SingleLiveEvent<>();
    public SingleLiveEvent<String> shelfName =new SingleLiveEvent<>();
    public SingleLiveEvent<String> shelfCode =new SingleLiveEvent<>();
    public ObservableList<ListingByCarItemViewModel> bookItemList = new ObservableArrayList<>();
    public ItemBinding<ListingByCarItemViewModel> bookitemBinding = ItemBinding.of(BR.viewModel, R.layout.item_listing_by_car);
    public ListingByCarViewModel(@NonNull Application application) {
        super(application,BusinessRepsitory.getInstance());
        Messenger.getDefault().register(this, TOKEN_CAMERA, String.class, carId -> {
           getCarInfoById(carId);
        });
        registerRFID(rfidService);
    }

    public void onScanResult(TagInfo tagInfo){

        switch (tagInfo.getRfidModel()) {
            case TID:
                if (tagInfo.getScanModel() == AnalyzeImpl.TO_SHELF) {
                    getShelfByTid(tagInfo.getTag());
                } else
                    getBookByTid(tagInfo.getTag());
                break;
            case EPC:
            case U_DATA:
                if (tagInfo.getScanModel() == AnalyzeImpl.TO_SHELF) {
                    getShelfByCode(tagInfo.getTag());
                } else
                    getBookByCode(tagInfo.getTag());
                break;
        }
    }
    private void getCarInfoById(String carId){
        tempBeans.clear();
        model.getBookCarInfo(carId)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(bookCarBean -> {
                    carName.postValue(bookCarBean.getCarName());
                    this.carId = bookCarBean.getCarId();
                    List<Observable<BaseBean<BookBean>>> collect = J8Arrays.stream(bookCarBean.getBookIds().split(";"))
                            .map(s -> model.getBookByCode(s)).collect(Collectors.toList());
                    getBooks(collect);
                });
    }
    List<BookBean> tempBeans = new ArrayList<>();
    private void getBooks(List<Observable<BaseBean<BookBean>>> collect){
        Observable.merge(collect)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(bean -> tempBeans.add(bean), throwable -> {}, () -> {
                    KLog.e("执行最后操作。。。。");
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        tempBeans.stream().sorted(Comparator.comparingInt(o->o.getShelfCode().hashCode())).forEach(bean -> addItem(bean));
                    }
                });
    }
    /**
     * 按tid取架
     *
     * @param tid 时间
     */
    private void getShelfByTid(String tid) {
        model.getShelfInfoByTid(tid)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(bean -> checkItem(bean));
    }
    /**
     * 查询货架信息
     *
     * @param code 标签
     */
    private void getShelfByCode(String code) {
        if (StringUtils.isEmpty(code))
            return;
        model.getShelfInfoByCode(code)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(bean -> checkItem(bean));
    }


    private void checkItem(ShelfBean bean) {
        this.shelfName.postValue(bean.getShelfName());
        this.shelfCode.postValue(bean.getShelfCode());
         StreamSupport.stream(bookItemList).forEach(viewModel -> {
             viewModel.checkMatch(bean.getShelfCode());
//             boolean equals = viewModel.book.getValue().getShelfCode().equals(bean.getShelfCode());
//             KLog.e(equals+ "-----"+viewModel.book.getValue().getShelfCode()+"    图书的code  "+bean.getShelfCode());
//             KLog.e("viewModel.book.getValue().getBookName() = " + viewModel.book.getValue().getBookName()+"    "+viewModel.isMathcShelf.getValue());
//             viewModel.isMathcShelf.postValue(equals);
//             KLog.e(viewModel.isMathcShelf.getValue());
         });
    }



    /**
     * 按Tid查询书本
     *
     * @param tid 标签
     */
    private void getBookByTid(String tid) {
        model.getBookByTid(tid)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(bookBean -> addItem(bookBean));
    }
    /**
     * 按Code查询书本
     *
     * @param code 标签
     */
    private void getBookByCode(String code) {
        model.getBookByCode(code)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(bookBean -> addItem(bookBean));
    }


    /**
     * 添加项目
     *
     * @param bean 豆
     */
    /**
     * 添加项目
     *
     * @param bean 豆
     */
    private void addItem(BookBean bean) {
            bookItemList.add(new ListingByCarItemViewModel(this, bean));
    }

    /**
     * 获取position的方式有很多种,indexOf是其中一种，常见的还有在Adapter中、ItemBinding.of回调里
     *
     * @return
     */
    public int getPosition(ListingByCarItemViewModel item) {
        return bookItemList.indexOf(item);
    }

    public void onItemRemove(ListingByCarItemViewModel item) {
        int position = bookItemList.indexOf(item);
        bookItemList.remove(position);
        adapter.notifyDataSetChanged();
        ToastUtils.showShort("删除成功");
    }

    public UIChangeObservable ui =new UIChangeObservable();
    public class UIChangeObservable {
    }

    public BindingCommand listingBooks =new BindingCommand(()->{
        listingBookByShelf();
    });
    private void listingBookByShelf(){
        List<BookBean> matchBooks = getMatchBooks();
        if (matchBooks==null|matchBooks.isEmpty()) {
            ToastUtils.showShort("当前书车中没有需要上架到该层架的图书");
            return;
        }
        model.upBook2ShelfFromCar(matchBooks,carId)
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(updateResult -> {
                    ToastUtils.showShort("上架"+shelfName.getValue()+"层位图书"+matchBooks.size()+"册成功!");
                    cleanRFIDCacheNotStop();
                    removeItemsByShelfCode(shelfCode.getValue());
                });
    }
    private void removeItemsByShelfCode(String shelfCode){
        Map<String, List<ListingByCarItemViewModel>> maps = StreamSupport.stream(bookItemList).collect(java8.util.stream.Collectors.groupingBy(viewModel -> viewModel.book.getValue().getShelfCode()));
        List<ListingByCarItemViewModel> listingByCarItemViewModels = maps.get(shelfCode);
        for (ListingByCarItemViewModel viewModel : listingByCarItemViewModels) {
            onItemRemove(viewModel);
        }
    }

    private List<BookBean> getMatchBooks(){
        return  StreamSupport.stream(bookItemList)
                .filter(viewModel -> viewModel.isMathcShelf.get())
                .map(viewModel -> viewModel.book.getValue()).collect(java8.util.stream.Collectors.toList());
    }

    public BindingCommand searchLayerCommand = new BindingCommand<String>(shelfCode -> {
        getUC().getHideKeyboardEvent().call();
        getShelfByCode(shelfCode);
    });
}
